//! Send和Sync trait示例
//!
//! 展示Rust中自动实现的Send和Sync trait
//!
//! ## 概念说明
//!
//! Rust标准库中提供了两个trait来处理并发代码中的所有权问题：
//! - `Send`：允许在线程间转移所有权
//! - `Sync`：允许多线程访问相同的值
//!
//! ## Send trait
//!
//! `Send`标记trait表明该类型的值可以在线程间安全地转移所有权。
//! 几乎所有基本类型都是`Send`的，除了原始指针（raw pointers）。
//! 如果一个类型完全由`Send`类型组成，那么它也是`Send`的。
//! 例如，`i32`是`Send`的，`Vec<i32>`也是`Send`的。
//!
//! ## Sync trait
//!
//! `Sync`标记trait表明该类型的引用可以安全地在线程间共享。
//! 换句话说，对于类型`T`，如果`&T`是`Send`的，那么`T`就是`Sync`的，
//! 这意味着引用可以被安全地发送到另一个线程。
//! 基本类型是`Sync`的，完全由`Sync`类型组成的类型也是`Sync`的。
//!
//! ## 手动实现Send和Sync
//!
//! 通常不需要手动实现`Send`和`Sync` trait。
//! 因为它们是标记trait，甚至都不需要实现任何方法。
//! 它们只是用来增强并发相关的不可变性保证。
//!
//! 手动实现这些trait需要使用`unsafe`，因为编译器无法验证你的类型是否满足这些保证。
//! 如果错误地实现了这些trait，就可能造成数据竞争等内存不安全问题。
//!
//! ## Send和Sync相关知识点
//!
//! | 知识点 | 说明 |
//! |--------|------|
//! | Send | 类型可以在线程间安全地转移所有权 |
//! | Sync | 类型的引用可以安全地在线程间共享 |
//! | 自动实现 | 大多数类型自动实现Send和Sync |
//! | `Rc<T>` | 不是Send也不是Sync |
//! | `Arc<T>` | 是Send也是Sync |
//! | 裸指针 | 不是Send也不是Sync |

use std::sync::{Arc, Mutex};
use std::thread;

/// 展示Send trait的使用
///
/// `Send` trait表示一个类型的所有权可以在线程间传递。
/// 大多数类型都实现了`Send` trait，但有一些例外，如`Rc<T>`。
pub fn send_trait_example() {
    let value = String::from("hello");

    // String类型实现了Send trait，所以可以在线程间移动
    let handle = thread::spawn(move || {
        println!("Value in thread: {}", value);
    });

    handle.join().unwrap();
}

/// 展示Sync trait的使用
///
/// `Sync` trait表示一个类型可以安全地在多个线程间共享引用。
/// 对于任意类型`T`，如果`&T`是`Send`的，则`T`是`Sync`的。
pub fn sync_trait_example() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    // Arc<T>类型实现了Sync trait，所以可以在多个线程间共享
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Counter value: {}", *counter.lock().unwrap());
}

/// 展示手动实现Send和Sync的注意事项
///
/// 注意：通常不需要手动实现Send和Sync，应让Rust自动实现
/// 这里仅用于演示目的
pub fn manual_send_sync() {
    // 大多数类型都自动实现了Send和Sync
    // 例如：
    // - 基本类型 (i32, bool, char等)
    // - 包含Send/Sync类型的复合类型 (Vec<T>, Box<T>, Option<T>等)
    // - 引用类型 (&T) 当T: Sync时

    let x = 5;
    let y = String::from("hello");
    let z = vec![1, 2, 3];

    // 这些类型都是Send和Sync的
    let handle = thread::spawn(move || {
        println!("x: {}, y: {}, z: {:?}", x, y, z);
    });

    handle.join().unwrap();
}

/// 展示不满足Send/Sync约束的情况
///
/// 某些类型不是Send也不是Sync的，例如`Rc<T>`。
/// 这些类型不能在线程间安全地传递或共享。
pub fn non_send_sync_example() {
    // Rc<T>类型不是Send的，因为它使用非线程安全的引用计数
    // 下面的代码会编译失败:
    /*
    let rc = std::rc::Rc::new(5);
    let handle = thread::spawn(move || {
        println!("{:?}", rc);
    });
    */

    // 为了解决这个问题，应该使用Arc<T>（原子引用计数）
    let arc = Arc::new(5);
    let handle = thread::spawn(move || {
        println!("{:?}", arc);
    });

    handle.join().unwrap();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_send_trait() {
        send_trait_example();
    }

    #[test]
    fn test_sync_trait() {
        sync_trait_example();
    }

    #[test]
    fn test_manual_send_sync() {
        manual_send_sync();
    }

    #[test]
    fn test_non_send_sync() {
        non_send_sync_example();
    }
}
